package com.bzframework.pro.authorize.adapter;

import com.bzframework.pro.authorize.context.ReactiveUserTokenContextHolder;
import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
import org.hswebframework.web.exception.NotFoundException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @Author bingzhong
 * @Date 2024/11/24 11:58
 * @Description
 */
public interface ReactiveServiceCrudControllerAdapter<E, K> extends ReactiveServiceCrudController<E, K> {


    @Override
    default Mono<E> add(@RequestBody Mono<E> payload) {
        return ReactiveUserTokenContextHolder
                .currentReactive()
                .flatMap(auth -> payload.map(entity -> applyAuthentication(entity, auth)))
                .switchIfEmpty(payload)
                .flatMap(entity -> getService().insert(Mono.just(entity)).thenReturn(entity));
    }

    @Override
    default Mono<SaveResult> save(@RequestBody Flux<E> payload) {
        return ReactiveUserTokenContextHolder
                .currentReactive()
                .flatMapMany(auth -> payload.map(entity -> applyAuthentication(entity, auth)))
                .switchIfEmpty(payload)
                .as(getService()::save);
    }

    @Override
    default Mono<Integer> add(@RequestBody Flux<E> payload) {
        return ReactiveUserTokenContextHolder
                .currentReactive()
                .flatMapMany(auth -> payload.map(entity -> applyAuthentication(entity, auth)))
                .switchIfEmpty(payload)
                .collectList()
                .as(getService()::insertBatch);
    }

    @Override
    default Mono<Boolean> update(@PathVariable K id, @RequestBody Mono<E> payload) {
        return ReactiveUserTokenContextHolder
                .currentReactive()
                .flatMap(auth -> payload.map(entity -> applyAuthentication(entity, auth)))
                .switchIfEmpty(payload)
                .flatMap(entity -> getService().updateById(id, Mono.just(entity)))
                .doOnNext(i -> {
                    if (i == 0) {
                        throw new NotFoundException();
                    }
                })
                .thenReturn(true);
    }

}
